# -*- coding: utf-8 -*-  

from PyQt4.QtCore import QTextCodec, QPoint, QSize
from PyQt4.QtGui import QWidget, QTreeWidgetItemIterator, QHBoxLayout
from PyQt4.QtGui import QDialog
from PyQt4.QtGui import QTextEdit
from PyQt4.QtGui import QFileSystemModel
from PyQt4.QtGui import QTreeView
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QTreeWidget
from PyQt4.QtCore import QStringList
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QLineEdit
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QCheckBox
from PyQt4.QtCore import SIGNAL
from PyQt4.QtCore import Qt
from PyQt4.QtNetwork import QFtp
from PyQt4.QtCore  import QUrl
from PyQt4.QtCore  import QLatin1String
from PyQt4.QtGui import QTreeWidgetItem
from PyQt4.QtCore  import QString
from PyQt4.QtGui  import QIcon
from PyQt4.QtGui  import QTabWidget
from PyQt4.QtGui  import QGridLayout
from PyQt4.QtGui  import QMenu
from PyQt4.QtGui  import QAction
from PyQt4.QtGui  import QCursor
from PyQt4.QtCore  import QFile
from PyQt4.QtCore  import QDir
from PyQt4.QtCore  import QIODevice,QVariant
from PyQt4.QtGui  import QMessageBox
from PyQt4.QtGui   import QProgressDialog,QInputDialog
from PyQt4.QtGui  import QPainter
from PyQt4.QtGui  import QColor
from PyQt4.QtGui  import QWidget
from PyQt4.QtGui  import QApplication
from PyQt4.QtGui  import QRadialGradient
from PyQt4.QtGui  import QBrush 
from settingBaseDialog import SettingBaseDialog
# from base.configfileparser import ConfigFileParser

class FileModel(QFileSystemModel):
    def __init__(self,parent = None):
        super(FileModel,self).__init__(parent)
        
    def headerData(self,section,orientation,role):
        if (orientation == Qt.Horizontal and role == Qt.DisplayRole):
            if section == 0:
                return QVariant(self.tr("Name"))
            if section == 1:
                return QVariant(self.tr("Size"))
            if section == 2:
                return QVariant(self.tr("Type"))
            if section == 3:
                return QVariant(self.tr("ModifyTime"))
        return QVariant()
class refreshButton(QPushButton):
    def __init__(self,parent = None):
        super(refreshButton,self).__init__(parent)
        self.setStyleSheet("QPushButton{border-radius:2px;}"
                           'QPushButton:hover{background-color:rgb(153,189,239);}'
                           'QPushButton:pressed{background-color:rgb(81,137,220);}')
class LocalWidget(QWidget):
       
    def __init__(self,parent = None):
        super(LocalWidget,self).__init__(parent)
        self.setStyleSheet("QWidget{border:1px solid #2261C7;}")
        self.localDir = QLineEdit()
        self.localDir.setStyleSheet("QLineEdit{height:20px;border-radius:1px;}")
        self.localDir.setEnabled(False)
        self.model = FileModel()
        self.model.setRootPath("")
        
        self.localFileList = QTreeView(self)
        self.localFileList.setModel(self.model)
        
        self.refreshButton = refreshButton()
        self.refreshButton.setIcon(QIcon("img/ftprefresh.png"))
        
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.localDir)
        hLayout.addWidget(self.refreshButton)
       
        index = self.model.index('')
        
        localPath = QDir.currentPath() if QDir.currentPath().endsWith('/') else QDir.currentPath()+'/'
        self.localDir.setText(localPath)
        self.localFileList.expand(index)
        self.localFileList.scrollTo(index)
        #self.localFileList.resizeColumnToContents(0)
        self.localFileList.setColumnWidth(0,150)
       
        layout = QVBoxLayout()
        layout.addLayout(hLayout)
        layout.addWidget(self.localFileList)
       
        self.setLayout(layout)
       
        self.connect(self.localFileList, SIGNAL("doubleClicked(const QModelIndex)"),self.setLocalDir)
        self.localFileList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.localFileList, SIGNAL("customContextMenuRequested(const QPoint&)"),self.showContextMenu)
       
        self.popMenu = QMenu(self.localFileList)
        self.upLoadAction = QAction(self.tr("Upload"),self.popMenu)
        self.popMenu.addAction(self.upLoadAction)
        self.upLoadAction.setEnabled(False)
        
        self.connect(self.refreshButton, SIGNAL('clicked()'),self.refreshFileTree)
        
    def refreshFileTree(self):
        self.model = FileModel()
        self.model.setRootPath("")
        self.localFileList.setModel(self.model)
       
    def setLocalDir(self,modelIndex):
        if not self.model.isDir(modelIndex):
            modelIndex = self.model.parent(modelIndex)
        localPath = self.model.filePath(modelIndex) if self.model.filePath(modelIndex).endsWith('/') else self.model.filePath(modelIndex)+'/'
        self.localDir.setText(localPath)

    def showContextMenu(self,pos):
        index = self.localFileList.indexAt(pos)
        if not self.model.filePath(index).isEmpty():
            if not self.model.isDir(index):
                self.upLoadAction.setEnabled(True)
            else:
                self.upLoadAction.setEnabled(False)
            self.popMenu.exec_(QCursor.pos())
       
       
       
class RemoteWidget(QWidget):
       
    def __init__(self,parent = None):
        super(RemoteWidget,self).__init__(parent)
        self.setStyleSheet("QWidget{border:1px solid #2261C7;}")
        self.remoteDir = QLineEdit()
        self.remoteDir.setStyleSheet("QLineEdit{height:20px;border-radius:1px;}")
        self.remoteDir.setEnabled(False)
        self.remoteFileList = QTreeWidget()
        self.remoteFileList.setEnabled(False)
        self.remoteFileList.setRootIsDecorated(False)
        self.remoteFileList.setHeaderLabels(QStringList() << self.tr(u"Name") << self.tr(u"Size") << self.tr(u"Time"))
        self.remoteFileList.header().setStretchLastSection(False)
        self.remoteFileList.setColumnWidth(0,150)
        self.isDirectory = {}
       
        self.cdButton = refreshButton()
        self.cdButton.setIcon(QIcon("img/cdtoparent.png"))
        self.cdButton.setEnabled(False)
        
        self.refreshButton = refreshButton()
        self.refreshButton.setIcon(QIcon("img/ftprefresh.png"))
        
        hLayout = QHBoxLayout()
        hLayout.addWidget(self.remoteDir)
        hLayout.addWidget(self.cdButton)
        hLayout.addWidget(self.refreshButton)
        layout = QVBoxLayout()
        layout.addLayout(hLayout)
        layout.addWidget(self.remoteFileList)
       
        self.setLayout(layout)
       
        self.remoteFileList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.remoteFileList, SIGNAL("customContextMenuRequested(const QPoint&)"),self.showContextMenu)
       
       
        self.popMenu = QMenu(self.remoteFileList)
        self.downLoadAction = QAction(self.tr("Download"),self.popMenu)
        self.rmAction = QAction(self.tr("Delete"),self.popMenu)
        self.mkdirAction = QAction(self.tr("New folder"),self.popMenu)
        self.popMenu.addAction(self.downLoadAction)
        self.popMenu.addAction(self.rmAction)
        self.popMenu.addAction(self.mkdirAction)
        self.downLoadAction.setEnabled(False)
        
       
    def showContextMenu(self,pos):
        item = self.remoteFileList.itemAt(pos)
        if item:
            if item.text(0) == self.tr('<Null>'):
                return 
            if not self.isDirectory[item.text(0)]:
                self.downLoadAction.setEnabled(True)
            else:
                self.downLoadAction.setEnabled(False)
            self.rmAction.setEnabled(True)
            self.mkdirAction.setEnabled(False)
        else:
            self.downLoadAction.setEnabled(False)
            self.rmAction.setEnabled(False)
            self.mkdirAction.setEnabled(True)
        self.popMenu.exec_(QCursor.pos())
         
class TextLabel(QLabel):
    def __init__(self, parent=None):
        super(TextLabel, self).__init__(parent)
        self.setAlignment(Qt.AlignRight|Qt.AlignBottom)
#         self.setFixedHeight()
        self.setStyleSheet("QLabel{color:#333333;font-size:12px;margin-bottom:2px;font-weight: bold}")
class InputLineEdit(QLineEdit):
    def __init__(self, parent=None):
        super(InputLineEdit, self).__init__(parent)
        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.setFixedWidth(170)
        self.setStyleSheet('QLineEdit{font:"SimHei";font-size:12px;'
            'height:18px;border:1px solid #2261C7;border-radius:1px;}')
class ConfirmButton(QPushButton):
    def __init__(self, parent=None):
        super(ConfirmButton, self).__init__(parent)
        self.setFixedSize(QSize(80,25))
        self.setStyleSheet('QPushButton{font: bold "SimHei";font-size:12px;border-radius:2px;color:#2261C8;'
                                                   'background-image:url(img/settingok.png);}'
                                       'QPushButton:hover{background-image:url(img/settingok1.png);}'
                                       'QPushButton:pressed{background-image:url(img/settingok2.png);}'
                                      )
class ServerInfoWidget(QWidget):
    def __init__(self,parent = None,username="",password="",host=""):
        super(ServerInfoWidget,self).__init__(parent)
        self.setFocus(True)
        self.serverLabel = TextLabel(self.tr("Host"))
        self.serverName = InputLineEdit('')
        self.serverName.setText(host)
        self.serverName.setContextMenuPolicy(Qt.NoContextMenu)
        self.portLabel = TextLabel(self.tr("Port"))
        self.portText = InputLineEdit(self.tr("21"))
        self.portText.setContextMenuPolicy(Qt.NoContextMenu)
        self.userLabel = TextLabel(self.tr("UserName"))
        self.userName = InputLineEdit()
        self.userName.setText(username)
        self.userName.setContextMenuPolicy(Qt.NoContextMenu)
        self.pwdLabel = TextLabel(self.tr("Password"))
        self.pwdName = InputLineEdit()
        self.pwdName.setEchoMode(InputLineEdit.Password)
        self.pwdName.setText(password)
        self.pwdName.setContextMenuPolicy(Qt.NoContextMenu)
        self.anonymousCheck = QCheckBox(self.tr("Anonymous login"))
        self.anonymousCheck.setStyleSheet("QCheckBox{font:'SimHei';font-size:12px;color:rgb(146,146,146);}")
        self.connectButton = ConfirmButton(self.tr("Connect"))
        self.isAnonymous = False
       
#         layout1 = QHBoxLayout()
#         layout2 = QHBoxLayout()
#         
#         layout1.addWidget(self.serverLabel)
#         layout1.addWidget(self.serverName)
#         layout1.addWidget(self.portLabel)
#         layout1.addWidget(self.portText)
#         layout1.addWidget(self.anonymousCheck)
#         
#         layout2.addWidget(self.userLabel)
#         layout2.addWidget(self.userName)
#         layout2.addWidget(self.pwdLabel)
#         layout2.addWidget(self.pwdName)
#         layout2.addWidget(self.connectButton)
        
        GridLayout = QGridLayout()
        GridLayout.addWidget(self.serverLabel, 0, 0)
        GridLayout.addWidget(self.serverName, 0, 1)
        GridLayout.addWidget(self.portLabel, 0, 2)
        GridLayout.addWidget(self.portText, 0, 3)
        GridLayout.addWidget(self.anonymousCheck, 0, 4)
        
        GridLayout.addWidget(self.userLabel, 1, 0)
        GridLayout.addWidget(self.userName, 1, 1)
        GridLayout.addWidget(self.pwdLabel, 1, 2)
        GridLayout.addWidget(self.pwdName, 1, 3)
        GridLayout.addWidget(self.connectButton, 1, 4)
        
#         mainLayout=QVBoxLayout()
#         mainLayout.setMargin(0)
#         mainLayout.setSpacing(0)
#         mainLayout.addLayout(layout1)
#         mainLayout.addLayout(layout2)
        self.setLayout(GridLayout)
       
        self.connect(self.anonymousCheck, SIGNAL("stateChanged(int)"),self.anonymousChecked)
        self.anonymousCheck.setChecked(False)
       
       
    def anonymousChecked(self,status):
        if status == Qt.Unchecked:
            self.userName.setEnabled(True)
            self.pwdName.setEnabled(True)
            self.isAnonymous = False
        if status == Qt.Checked:
            self.userName.setEnabled(False)
            self.pwdName.setEnabled(False)
            self.isAnonymous = True

class OutPutInfoWidget(QWidget):
       
    def __init__(self,parent = None):
        super(OutPutInfoWidget,self).__init__(parent)
#         self.output = QWidget(self)
#         self.output.setTabPosition(QTabWidget.South)
        self.logText = QTextEdit(self)
#         self.logText.setFixedSize(QSize(self.width(),self.height()))
#         self.logText.setStyleSheet("QTextEdit{background-color:red;}")
        self.logText.setReadOnly(True)
#         self.output.addTab(self.logText, self.tr("Log"))
        self.setStyleSheet("QWidget{border:1px solid #2261C7;}")
        layout = QHBoxLayout()
        layout.addWidget(self.logText)
        layout.setMargin(0)
        layout.setSpacing(10)
        self.setLayout(layout)
        self.logText.append(self.tr("Welcome to the FTP tool ..."))
       
    def insertLogInfo(self,string):
        info = QString("<font color=#000000> > %1 </font>").arg(string)
        self.logText.append(info)
        scrollbar = self.logText.verticalScrollBar()
        scrollbar.setSliderPosition(scrollbar.maximum())
       
    def insertCommand(self,string):
        info = QString("<font color=#0011ff> > %1 </font>").arg(string)
        self.logText.append(info)
       
       
class FtpWidget(SettingBaseDialog):
       
    def __init__(self,parent = None,username="",password="",host=""):
        super(FtpWidget,self).__init__(parent)
        
#         self.configfileParser = ConfigFileParser().instance()
#         self.setModal(True)
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.CustomizeWindowHint)
        self.setFixedSize(QSize(670,500))
        self.tittleLabel.setFixedSize(QSize(670,self.tittleLabel.height()))
        self.setTittleText(self.tr("FTP Tool"))
        self.currentUser = ""
        self.fileList = []
       
        self.serverInfo = ServerInfoWidget(self,username=username,password=password,host=host)
        self.serverInfo.setFixedSize(QSize(670,80))
        self.localInfo = LocalWidget(self)
        self.localInfo.setFixedSize(QSize(335, 345))
        self.remoteInfo = RemoteWidget(self)
        self.remoteInfo.setFixedSize(QSize(335, 345))
        self.outputInfo = OutPutInfoWidget(self)
        self.outputInfo.setFixedSize(QSize(670, 110))
        
        self.outputInfo.hide()
        
        self.outputInfoStstus = False
        self.logButton = QPushButton(self)
        self.logButton.setIcon(QIcon("img/log.png"))
        self.logButton.setFixedSize(QSize(18,20))
        self.logButton.setStyleSheet("QPushButton{border-radius:2px;width:80px;height:25px}"
                                       'QPushButton:hover{background-color:rgb(153,189,239);}'
                                       "QPushButton:pressed{background-color:rgb(81,137,220);}")
        
        self.logLabel = QLabel(self)
        self.logLabel.setText(self.tr('Log'))
        self.logLabel.setFixedSize(QSize(32,20))
        self.logLabel.setStyleSheet("QLabel{font:'SimHei';font-size:12px;}")
        
        self.logWidget = QWidget(self)
        self.logWidget.setFixedSize(QSize(50,20))
        logWidgetHlayout = QHBoxLayout(self.logWidget)
        logWidgetHlayout.setMargin(0)
        logWidgetHlayout.setSpacing(0)
        logWidgetHlayout.addWidget(self.logButton)
        logWidgetHlayout.addSpacing(3)
        logWidgetHlayout.addWidget(self.logLabel)
        
        logButtonLayout = QHBoxLayout()
        logButtonLayout.setMargin(0)
        logButtonLayout.setSpacing(0)
        logButtonLayout.addSpacing(20)
        logButtonLayout.addWidget(self.logWidget)
        logButtonLayout.addStretch()
        
        dirLayout = QHBoxLayout()
        dirLayout.setMargin(0)
        dirLayout.setSpacing(0)
        dirLayout.addWidget(self.localInfo)
        dirLayout.addWidget(self.remoteInfo)
       
        ftpLayout = QVBoxLayout()
        ftpLayout.addWidget(self.serverInfo)
        ftpLayout.addLayout(dirLayout)
#         self.setWindowTitle(self.tr("FTP Tool"))
       
        GridLayout = QGridLayout()
        GridLayout.setMargin(0)
        GridLayout.setSpacing(0)
        GridLayout.addLayout(ftpLayout, 0, 0)
        GridLayout.addLayout(logButtonLayout,1,0)
        GridLayout.addWidget(self.outputInfo, 2, 0)
        GridLayout.setRowStretch(0,5)
        GridLayout.setRowStretch(2,1)
        
        mainLayout=QVBoxLayout()
#         mainLayout.addSpacing(self.tittleLabel.height())
        
        mainLayout.setMargin(0)
        mainLayout.setSpacing(0)
        mainLayout.addSpacing(35)
#         mainLayout.addStretch()
        mainLayout.addLayout(GridLayout)
        self.setLayout(mainLayout)
       
        self.connect(self.serverInfo.connectButton, SIGNAL("clicked()"),self.connectOrDisconnect)
        self.connect(self.remoteInfo.remoteFileList,SIGNAL("itemActivated(QTreeWidgetItem*,int)"),self.processItem)
        self.connect(self.remoteInfo.downLoadAction, SIGNAL("triggered()"),self.downLoadFile)
        self.connect(self.remoteInfo.rmAction, SIGNAL("triggered()"),self.removeFile)
        self.connect(self.remoteInfo.mkdirAction, SIGNAL("triggered()"),self.mkDirectory)
        self.connect(self.localInfo.upLoadAction, SIGNAL("triggered()"),self.upLoadFile)
        self.connect(self.logButton, SIGNAL("clicked()"), self.slotHideLog)
       
        self.connected = False
        self.transFile = QFile("")
        self.ftp = QFtp(self)
        self.progressDialog = QProgressDialog(self,Qt.CustomizeWindowHint|Qt.WindowCloseButtonHint)
        self.progressDialog.setWindowIcon(QIcon("img/ftp.png"))
        self.progressDialog.setCancelButton(None)
        self.progressDialog.setWindowModality(Qt.ApplicationModal)
        self.connect(self.progressDialog, SIGNAL("canceled()"),self.cancelFileTrans)
#         self.setWindowIcon(QIcon('img/ftp.png'))
        self.transfilecancle = False
#         self.setWindowFlags(Qt.CustomizeWindowHint|Qt.WindowCloseButtonHint)
        self.connect(self.remoteInfo.refreshButton, SIGNAL('clicked()'),self.refreshRemoteFileTree)
        if username!="" and password != "" and host !="":
            self.connectOrDisconnect()
            self.outputInfo.insertLogInfo(self.tr("Connecting FTP Server ..." ))
    def slotHideLog(self):
        if self.outputInfoStstus == False:
            self.outputInfoStstus = True
            self.outputInfo.show()
            self.setFixedSize(QSize(self.width(),590))
        else:
            self.outputInfoStstus = False
            self.outputInfo.hide()
            self.setFixedSize(QSize(self.width(),500))
    def refreshRemoteFileTree(self):
        self.remoteInfo.remoteFileList.clear()
        self.ftp.list()
        self.getRomoteFileList()
         
    def __del__(self):
        if self.transFile.isOpen():
            self.transFile.close()
        if self.connected:
            self.ftp.abort()
            self.ftp.close()
             
    def getRomoteFileList(self):
        #self.remoteInfo.remoteFileList.currentItem().text(0)
        self.fileList = []
        
        for item in self.remoteInfo.isDirectory:
            if not self.remoteInfo.isDirectory[item]:
                return
                self.fileList.append(item)
         
 
    def cancelFileTrans(self):
        self.ftp.abort()
        self.outputInfo.insertLogInfo(self.tr("File transfer canceled"))
        self.transfilecancle = True
         
    def mkDirectory(self):
        if self.currentUser == "image" or self.currentUser == "vhost":
            QMessageBox.critical(self,self.tr("Critical"),self.tr("There is no need to create a directory!"))
            return
        dirName = QInputDialog.getText(None, self.tr("New folder"),self.tr("Name："),QLineEdit.Normal, self.tr("New folder"))[0]
        self.ftp.mkdir(QString(QTextCodec.codecForName("utf-8").fromUnicode(dirName)))
        
    def upLoadFile(self):
        self.transfilecancle = False
        localFileName = self.localInfo.model.filePath(self.localInfo.localFileList.currentIndex())
        fileName = localFileName.mid(localFileName.lastIndexOf('/')+1)
        
        if self.currentUser == "image" or self.currentUser == "vhost":
            self.getRomoteFileList()
            if fileName in self.fileList:
                QMessageBox.critical(self,self.tr("Critical"),self.tr("This file is exist in the FtpServer, upload it after change the name of this file!"))
                return
        
        self.transFile = QFile(localFileName)
        if not self.transFile.open(QIODevice.ReadOnly):
            QMessageBox.information(self, self.tr("Uplaod"),
                                 self.tr("Cannot open file %1: %2.")
                                 .arg(localFileName).arg(self.transFile.errorString()))
            self.transFile.close()
            return
        if self.ftp.state() != QFtp.Unconnected:
            self.ftp.put(self.transFile,QString(QTextCodec.codecForName("utf-8").fromUnicode(fileName)))
            self.outputInfo.insertLogInfo(self.tr("Start uploading files:") +self.transFile.fileName())
        else:
            self.outputInfo.insertLogInfo(self.tr("Faild To Connect FTP Server" ))
            return
        self.progressDialog.setWindowTitle(self.tr("Upload"))
        self.progressDialog.setLabelText(self.tr("Upload Files： %1...").arg(fileName))
        
    def removeFile(self):
        fileName = self.remoteInfo.remoteFileList.currentItem().text(0)
         
        if self.currentUser == "image" or self.currentUser == "vhost":
            QMessageBox.critical(self,self.tr("Critical"),self.tr("This action will be leading to creating errors in the CCR-Host!"))
            return
        if self.remoteInfo.isDirectory[fileName]:
            self.ftp.rmdir(QString(QTextCodec.codecForName("utf-8").fromUnicode(fileName)))
        else:
            self.ftp.remove(QString(QTextCodec.codecForName("utf-8").fromUnicode(fileName)))
 
    def downLoadFile(self):
        self.transfilecancle = False
        fileName = self.remoteInfo.remoteFileList.currentItem().text(0)
        localFileName = self.localInfo.localDir.text() + fileName
                                
        self.transFile = QFile(localFileName)
        if not self.transFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, self.tr("Download"),
                                 self.tr("Unable To Save File： %1: %2.")
                                 .arg(localFileName).arg(self.transFile.errorString()))
            self.transFile.close()
            return
        self.ftp.get(QString(QTextCodec.codecForName("utf-8").fromUnicode(fileName)), self.transFile)
        self.outputInfo.insertLogInfo(self.tr("Begin Download File:") +self.transFile.fileName())
        
        self.progressDialog.setWindowTitle(self.tr("Download"))
        self.progressDialog.setLabelText(self.tr("Download Files： %1...").arg(fileName))      
        
        
    # 双击目录时，进入下一级目录
    def processItem(self,item, column):
        dirName = item.text(0)
        if item.text(0) == self.tr('<空>'):
            return 
        if self.remoteInfo.isDirectory[dirName]:
            self.remoteInfo.remoteFileList.clear()
            self.remoteInfo.isDirectory.clear()
            currentdir = self.remoteInfo.remoteDir.text()+ '/'
            currentdir += dirName
            self.remoteInfo.remoteDir.setText(currentdir)
            self.ftp.cd(QString(QTextCodec.codecForName("utf-8").fromUnicode(dirName)))
            self.ftp.list()
            #self.outputInfo.insertCommand(self.tr("cd ")+dirName)
            self.outputInfo.insertLogInfo(self.tr("Change Directory:")+dirName)
    def keyPressEvent(self, k):
        if k.key() == Qt.Key_Enter or k.key() == Qt.Key_Return:
            self.connectOrDisconnect()
    # 连接ftp
    def connectOrDisconnect(self):
        self.serverInfo.connectButton.setEnabled(False)
        if self.connected:
            self.ftp.abort()
            self.ftp.close()
            self.disconnect(self.ftp, SIGNAL("commandFinished(int,bool)"),self.ftpCommandFinished)
            self.disconnect(self.ftp, SIGNAL("listInfo(QUrlInfo)"),self.addToList)
            self.disconnect(self.ftp, SIGNAL("dataTransferProgress(qint64,qint64)"),self.updateDataTransferProgress)
            self.disconnect(self.remoteInfo.cdButton, SIGNAL("clicked()"),self.cdToParent)
            self.connected = False
            self.remoteInfo.remoteFileList.clear()
            self.remoteInfo.remoteDir.clear()
            self.remoteInfo.remoteFileList.setEnabled(False)
            self.serverInfo.connectButton.setEnabled(True)
            self.serverInfo.connectButton.setText(self.tr("Connecting"))
            self.serverInfo.anonymousCheck.setEnabled(True)
            self.serverInfo.serverName.setEnabled(True)
            self.serverInfo.portText.setEnabled(True)
            self.remoteInfo.isDirectory.clear()
            self.outputInfo.insertLogInfo(self.tr("Disconnect"))
            if self.transFile.isOpen():
                self.transFile.close()
            return
        self.ftp = QFtp(self)
        self.remoteInfo.isDirectory.clear()
        self.connect(self.ftp, SIGNAL("commandFinished(int,bool)"),self.ftpCommandFinished)
        self.connect(self.ftp, SIGNAL("listInfo(QUrlInfo)"),self.addToList)
        self.connect(self.ftp, SIGNAL("dataTransferProgress(qint64,qint64)"),self.updateDataTransferProgress)
        self.connect(self.ftp, SIGNAL("done(bool)"),self.ftpDone)
        
        self.remoteInfo.remoteFileList.clear()
        
        # 不是匿名登陆时，需要有用户名，否则不处理
        if not self.serverInfo.isAnonymous and self.serverInfo.userName.text().isEmpty():
            self.outputInfo.insertLogInfo(self.tr("Please enter a username or anonymous login"))
            self.serverInfo.connectButton.setEnabled(True)
            return
        
        # 登陆
        url = QUrl(self.serverInfo.serverLabel.text())
        if (not url.isValid()) or (url.scheme().toLower() != QLatin1String("ftp")):
            self.ftp.connectToHost(self.serverInfo.serverName.text(), self.serverInfo.portText.text().toInt()[0])
            if self.serverInfo.isAnonymous:
                self.ftp.login()
            else:
                self.ftp.login(self.serverInfo.userName.text(),self.serverInfo.pwdName.text())
                self.currentUser = self.serverInfo.userName.text()
                 
        else:
            self.ftp.connectToHost(url.host(),url.port(21))
            if not url.userName().isEmpty():
                self.ftp.login(QUrl.fromPercentEncoding(url.userName().toLatin1()), url.password())
            else:
                self.ftp.login()
        self.remoteInfo.remoteFileList.clear()
        self.remoteInfo.isDirectory.clear()
        
    def ftpDone(self,error):
        if error:
            self.progressDialog.hide()
            self.outputInfo.insertLogInfo(self.ftp.errorString())
            self.ftp.abort()
            self.ftp.close()
            self.disconnect(self.ftp, SIGNAL("commandFinished(int,bool)"),self.ftpCommandFinished)
            self.disconnect(self.ftp, SIGNAL("listInfo(QUrlInfo)"),self.addToList)
            self.disconnect(self.ftp, SIGNAL("dataTransferProgress(qint64,qint64)"),self.updateDataTransferProgress)
            self.disconnect(self.remoteInfo.cdButton, SIGNAL("clicked()"),self.cdToParent)
            self.connected = False
            self.remoteInfo.remoteFileList.clear()
            self.remoteInfo.remoteDir.clear()
            self.remoteInfo.remoteFileList.setEnabled(False)
            self.serverInfo.connectButton.setEnabled(True)
            self.serverInfo.connectButton.setText(self.tr("Connecting"))
            self.serverInfo.anonymousCheck.setEnabled(True)
            self.serverInfo.serverName.setEnabled(True)
            self.serverInfo.portText.setEnabled(True)
            self.remoteInfo.isDirectory.clear()
            if self.transFile.isOpen():
                self.transFile.close()
            return
            #self.connectOrDisconnect()
    def updateDataTransferProgress(self,readBytes,totalBytes):
        self.progressDialog.setMaximum(100)
        self.progressDialog.setValue(readBytes*100/totalBytes)
        if readBytes < totalBytes:
            self.progressDialog.show()
        else:
            self.progressDialog.hide()
    
    # 返回上一级目录
    def cdToParent(self):
        self.remoteInfo.remoteFileList.clear()
        self.remoteInfo.isDirectory.clear()
        currentPath = self.remoteInfo.remoteDir.text()
        currentPath = currentPath.left(currentPath.lastIndexOf('/'))
        
        if not currentPath:
            self.remoteInfo.cdButton.setEnabled(False)
        self.ftp.cd('..')
        self.ftp.list()
        self.remoteInfo.remoteDir.setText(currentPath)
        #self.outputInfo.insertCommand(self.tr("cd .."))
        self.outputInfo.insertLogInfo(self.tr("Return To Parent Directory"))
        
    # ftp状态变化时的相应处理
    def ftpCommandFinished(self,id,error):
        if self.ftp.currentCommand() == QFtp.ConnectToHost:
            if error:
                self.outputInfo.insertLogInfo(self.tr("Connect FTP Server: ")+self.serverInfo.serverName.text()+self.tr(" Fialed"))
                #self.connectOrDisconnect()
                self.serverInfo.connectButton.setEnabled(True)
                return
            self.outputInfo.insertLogInfo(self.tr("Connect FTP Server: ")+self.serverInfo.serverName.text())
                        
        if self.ftp.currentCommand() == QFtp.Login:
            if error:
                self.serverInfo.connectButton.setEnabled(True)
                return
            self.outputInfo.insertLogInfo(self.tr("Land Success"))
            self.connect(self.remoteInfo.cdButton, SIGNAL("clicked()"),self.cdToParent)
            self.ftp.list()
            self.connected = True
            self.serverInfo.connectButton.setEnabled(True)
            self.serverInfo.anonymousCheck.setEnabled(False)
            self.serverInfo.connectButton.setText(self.tr("Disconnect"))
            self.serverInfo.serverName.setEnabled(False)
            self.serverInfo.portText.setEnabled(False)
            
        if self.ftp.currentCommand() == QFtp.List:
            if not self.remoteInfo.remoteDir.text().isEmpty():
                self.remoteInfo.cdButton.setEnabled(True)
            if not self.remoteInfo.isDirectory:
                self.remoteInfo.remoteFileList.addTopLevelItem(QTreeWidgetItem(QStringList() << self.tr("<Null>")))
                self.remoteInfo.remoteFileList.setEnabled(True)
                
        if self.ftp.currentCommand() == QFtp.Get:
            if error:
                self.transFile.close()
            else:
                self.outputInfo.insertLogInfo(self.tr("Download Files:")+ self.transFile.fileName() +(self.tr(" Success") if self.transfilecancle == False else self.tr("Failed")))
            self.transFile.close()
                
        if self.ftp.currentCommand() == QFtp.Put:
            if error:
                self.transFile.close()
            else:
                self.outputInfo.insertLogInfo(self.tr("Upload Files:")+ self.transFile.fileName() +(self.tr(" Success") if self.transfilecancle == False else self.tr("Failed")))
                self.remoteInfo.remoteFileList.clear()
                self.ftp.list()
            self.transFile.close()
            if self.transfilecancle == True:
                self.ftp.remove(self.transFile.fileName().split('/')[-1])
        if self.ftp.currentCommand() == QFtp.Remove:
            if not error:
                self.outputInfo.insertLogInfo(self.tr("Delete File:")+ (self.remoteInfo.remoteFileList.currentItem().text(0) if not self.transfilecancle else self.transFile.fileName().split('/')[-1]) +self.tr(" Success"))
                self.remoteInfo.remoteFileList.clear()
                self.ftp.list()
                 
        if self.ftp.currentCommand() == QFtp.Rmdir:
            if not error:
                self.outputInfo.insertLogInfo(self.tr("Delete Directory:<")+ self.remoteInfo.remoteFileList.currentItem().text(0) +self.tr("> Success"))
                self.remoteInfo.remoteFileList.clear()
                self.ftp.list()
                 
        if self.ftp.currentCommand() == QFtp.Mkdir:
            if not error:
                self.outputInfo.insertLogInfo(self.tr("Create a directory Success"))
                 
                self.remoteInfo.remoteFileList.clear()
                self.ftp.list()
         
    
    # 向文件列表添加目录和文件
    def addToList(self,urlInfo):
        item =QTreeWidgetItem()
         
        item.setText(0, QTextCodec.codecForName("utf-8").toUnicode(urlInfo.name().toLatin1()))
        item.setText(1, QString.number(urlInfo.size()))
        item.setText(2, urlInfo.lastModified().toString("MMM dd yyyy"))
        
        self.remoteInfo.isDirectory[QTextCodec.codecForName("utf-8").toUnicode(urlInfo.name().toLatin1())] = urlInfo.isDir()
        
        fileIcon = QIcon("img/dir.png" if urlInfo.isDir() else "img/file.png")
        item.setIcon(0,fileIcon)
        self.remoteInfo.remoteFileList.addTopLevelItem(item)
        if not self.remoteInfo.remoteFileList.currentItem():
            self.remoteInfo.remoteFileList.setCurrentItem(self.remoteInfo.remoteFileList.topLevelItem(0))
            self.remoteInfo.remoteFileList.setEnabled(True)
    
#     def paintEvent(self,paintEvent):
#         painter = QPainter(self)
#         # 设置背景颜色
#         radialGradient = QRadialGradient(800,800,1000,800,600)
#         radialGradient.setColorAt(1,QColor(48,123,231))
#         radialGradient.setColorAt(0,QColor(48,123,231))
#         painter.setBrush(QBrush(radialGradient))  
#         painter.setPen(QColor(255,255,255,0)) # 去除边框
#         painter.drawRect(QApplication.desktop().screenGeometry())

class FTPDialog(SettingBaseDialog):
    def __init__(self, parent=None, username="",password="",host=""):
        super(FTPDialog, self).__init__(parent)
        user = "hepeng"
        password = "share"
        host = "192.168.7.40"
        self.FTPWidget = FtpWidget(username=user,password=password,host=host)
        self.setFixedSize(QSize(670,590))
        self.tittleLabel.setFixedSize(QSize(670,self.tittleLabel.height()))
        self.setTittleText(self.tr("FTP Tool"))
        self.FTPWidget.move(QPoint(0,self.tittleLabel.height()))




from PyQt4.QtCore import QTextCodec,QObject
from PyQt4.QtGui import QApplication

import sys, getopt


QTextCodec.setCodecForTr(QTextCodec.codecForName("utf-8"))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    user = "share"
    password = "share"
    host = "192.168.7.41"
    mainframe = FtpWidget(username=user,password=password,host=host)
    mainframe.show()
    sys.exit(app.exec_())